package top.yuechenc.manage.controller;

import io.swagger.annotations.*;
import org.apache.tomcat.util.buf.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.yuechenc.manage.common.token.ShopResult;
import top.yuechenc.manage.common.token.UserLoginToken;
import top.yuechenc.manage.entity.SpPermissionDto;
import top.yuechenc.manage.entity.SpRole;
import top.yuechenc.manage.entity.SpRoleDto;
import top.yuechenc.manage.service.PermissionApiService;
import top.yuechenc.manage.service.PermissionService;
import top.yuechenc.manage.service.RoleService;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 角色管理接口
 *
 * @author Zhiwei Wang
 * @date 2020/3/12 15:58
 */
@Api(description = "角色管理接口")
@RestController
@RequestMapping(value = "/api/roles")
public class RoleController {
    private static final Logger log = LoggerFactory.getLogger(RoleController.class);

    @Autowired
    private RoleService roleService;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private PermissionApiService permissionApiService;

    /**
     * 获取角色列表--列表包含角色的所有权限
     *
     * @author Zhiwei Wang
     * @date 2020/3/12 17:41
     */
    @UserLoginToken
    @ApiOperation(value = "获取带权限的角色列表")
    @GetMapping(value = "/getRoleList")
    private ShopResult getRoleList() {
        ShopResult res = null;
        List<SpRoleDto> roleList = null;
        try {
            roleList = roleService.getRoleList();
            for (int i = 0; i < roleList.size(); i++) {
                List<SpPermissionDto> list = new ArrayList<>();
                String spIds = roleList.get(i).getPsIds();
                List<String> result = Arrays.asList(spIds.split(","));
                for (int j = 0; j < result.size(); j++) {
                    SpPermissionDto spPermission = permissionService.getById(result.get(j));
                    if (spPermission != null) {
                        list.add(spPermission);
                    }
                }
                roleList.get(i).setChildren(findChildren(list, "0"));
            }
            res = new ShopResult(ShopResult.Metaa.SELECT, roleList);
            log.info("获取带权限的角色列表={}",res);
        } catch (Exception e) {
            e.printStackTrace();
            log.debug(e.toString());
            res = new ShopResult(ShopResult.Metaa.SELECT_FAIL, e);
        }
        return res;
    }

    @UserLoginToken
    @ApiOperation(value = "新增角色")
    @PostMapping(value = "/addRole")
    private ShopResult addRole(@RequestBody @ApiParam(name = "角色对象", value = "传入json格式") SpRole spRole) {
        ShopResult result;
        if (spRole != null) {
            spRole.setRoleId(UUID.randomUUID().toString());
            try {
                roleService.addRole(spRole);
                log.info("新增角色,role={}",spRole);
                result = new ShopResult(ShopResult.Metaa.CREATED, spRole);
            } catch (Exception e) {
                e.printStackTrace();
                log.debug(e.toString());
                result = new ShopResult(ShopResult.Metaa.CREATED_FAIL, e.getMessage());
            }
        } else {
            result = new ShopResult(ShopResult.Metaa.CREATED_FAIL, "创建失败：管理员信息不能为空！");
        }
        return result;
    }

    @ApiOperation(value = "根据Id查询角色")
    @GetMapping(value = "/getById")
    @UserLoginToken
    @ApiImplicitParam(name = "roleId", value = "角色编号", dataType = "string", paramType = "query", required = true)
    private ShopResult getById(String roleId) {
        ShopResult result;
        SpRole spRole=new SpRole();
        try {
            if (roleId != null && !"".equals(roleId)) {
                spRole = roleService.findRoleById(roleId);
                if (spRole != null) {
                    result = new ShopResult(ShopResult.Metaa.SELECT, spRole);
                } else {
                    result = new ShopResult(ShopResult.Metaa.SELECT_FAIL, "未查到该编号对应的角色");
                }
            } else {
                result = new ShopResult(ShopResult.Metaa.SELECT_FAIL, "请输入管理员编号！");
            }
            log.info("根据Id查询角色,role={}",spRole);
        } catch (Exception e) {
            e.printStackTrace();
            log.debug(e.toString());
            result=new ShopResult(ShopResult.Metaa.SELECT_FAIL, e);
        }
        return result;
    }

    @ApiOperation(value = "修改角色")
    @PostMapping(value = "/update")
    @UserLoginToken
    private ShopResult update(@RequestBody @ApiParam(name = "角色对象", value = "传入json格式") SpRole spRole) {
        ShopResult res;
        if (spRole.getRoleId() != null && !"".equals(spRole.getRoleId())) {
            try {
                roleService.updById(spRole);
                spRole = roleService.findRoleById(spRole.getRoleId());
                log.info("修改角色,role={}",spRole);
                res = new ShopResult(ShopResult.Metaa.UPDATE, spRole);
            } catch (Exception e) {
                e.printStackTrace();
                log.debug(e.toString());
                res = new ShopResult(ShopResult.Metaa.UPDATE_FAIL, e.getMessage());
            }
        } else {
            res = new ShopResult(ShopResult.Metaa.UPDATE_FAIL, "：请输入角色编号！");
        }
        return res;
    }

    private List<SpPermissionDto> findChildren(List<SpPermissionDto> list, String pid) {
        List<SpPermissionDto> spoList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getPsPid() != null && list.get(i).getPsPid().equals(pid)) {
                spoList.add(list.get(i));
            }
        }
        if (spoList.size() > 0) {
            for (SpPermissionDto spof : spoList) {
                spof.setChildren(findChildren(list, spof.getPsId()));
            }
            return spoList;
        } else {
            return spoList;
        }
    }


    @ApiOperation(value = "删除角色")
    @GetMapping(value = "/del")
    @UserLoginToken
    @ApiImplicitParam(name = "roleId", value = "角色编号", dataType = "string", paramType = "query", required = true)
    private ShopResult deleteRole(String roleId) {
        ShopResult res;
        if (roleId != null && !"".equals(roleId)) {
            try {
                roleService.delById(roleId);
                log.info("删除角色,roleId={}",roleId);
                res = new ShopResult(ShopResult.Metaa.DELETED);
            } catch (Exception e) {
                e.printStackTrace();
                log.debug(e.toString());
                res = new ShopResult(ShopResult.Metaa.DELETED_FAIL, e.getMessage());
            }
        } else {
            res = new ShopResult(ShopResult.Metaa.DELETED_FAIL, "：请输入角色编号！");
        }
        return res;
    }

    @ApiOperation(value = "为角色分配权限")
    @PostMapping(value = "/setRights")
    @UserLoginToken
    private ShopResult setRights(@RequestBody @ApiParam(name = "角色对象", value = "传入json格式") SpRole spRole) {
        ShopResult res;
        if (spRole.getRoleId() == null || "".equals(spRole.getRoleId())) {
            res = new ShopResult(ShopResult.Metaa.UPDATE_FAIL, "：请输入角色编号！");
        } else {
            SpRole spRole1 = roleService.findRoleById(spRole.getRoleId());
            spRole1.setPsIds(spRole.getPsIds());
            try {
                roleService.setRights(spRole1);
                log.info("为角色分配权限,role={}",spRole1);
                res = new ShopResult(ShopResult.Metaa.UPDATE, spRole1);
            } catch (Exception e) {
                e.printStackTrace();
                log.debug(e.toString());
                res = new ShopResult(ShopResult.Metaa.UPDATE_FAIL, e.getMessage());
            }
        }
        return res;
    }

    @ApiOperation(value = "根据角色编号删除权限")
    @GetMapping(value = "/delRights")
    @UserLoginToken
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色编号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "rightId", value = "权限编号", dataType = "string", paramType = "query", required = true)
    })
    private ShopResult delRights(String roleId, String rightId) {
        ShopResult res;
        if (roleId == null || "".equals(roleId)) {
            res = new ShopResult(ShopResult.Metaa.DELETED_FAIL, "：请输入角色编号！");
        } else if (rightId == null || "".equals(rightId)) {
            res = new ShopResult(ShopResult.Metaa.DELETED_FAIL, "：请输入权限编号！");
        } else {
            SpRole spRole = roleService.findRoleById(roleId);
            String psIdsV = "";

            // 拆分成数组
            String[] psIds = spRole.getPsIds().split(",");
            // 数组转集合
            List<String> psIdsList = new ArrayList<String>(Arrays.asList(psIds));
            // 移除指定权限 ID
            psIdsList.remove(rightId.toString());
            // 把剩下的权限 ID 再拼接起来
            psIdsV = StringUtils.join(psIdsList, ',');
            spRole.setPsIds(psIdsV);
            try {
                roleService.updById(spRole);

                SpRoleDto spRoleDto = handleSpRole(spRole);
                List<SpPermissionDto> list = new ArrayList<>();
                String spIds = spRoleDto.getPsIds();
                List<String> result = Arrays.asList(spIds.split(","));
                for (String s : result) {
                    SpPermissionDto spPermission = permissionService.getById(s);
                    if (spPermission != null) {
                        list.add(spPermission);
                    }
                }
                spRoleDto.setChildren(findChildren(list, "0"));

                log.info("根据角色编号删除权限");
                res = new ShopResult(ShopResult.Metaa.DELETED, spRoleDto.getChildren());
            } catch (Exception e) {
                e.printStackTrace();
                log.debug(e.toString());
                res = new ShopResult(ShopResult.Metaa.DELETED_FAIL, e.getMessage());
            }
        }
        return res;
    }


    private SpRoleDto handleSpRole(SpRole spRole) {
        SpRoleDto spRoleDto = new SpRoleDto();
        spRoleDto.setRoleId(spRole.getRoleId());
        spRoleDto.setPsIds(spRole.getPsIds());
        spRoleDto.setPsCa(spRole.getPsCa());
        spRoleDto.setRoleDesc(spRole.getRoleDesc());
        spRoleDto.setRoleName(spRole.getRoleName());
        return spRoleDto;
    }
}
